#region Copyright RenGuiYou. All rights reserved.

//=====================================================
// NeatlyFrameWork
// Author:      RenGuiyou
// Feedback: 	mailto:750539605@qq.com
//=====================================================

#endregion

using UnityEngine;
using System.Globalization;
using System.Text;
using Neatly.UI;
using UnityEngine.UI;

namespace Neatly.Tween
{

    public sealed class EffectTweenRtPosObj : EffectTweenObjectBase
    {
        private enum MoveType
        {
            Anchored, //UI
            Position, //世界坐标
            LocalPosition, //区域坐标
            Scale,
            Rotate,
            AutoRotate,
            ImageColor,
            SizeDelta,
        }

        private enum TweenType
        {
            Lerp,
            Bezier,
        }


        private RectTransform _rectTransform;
        private Transform _transform;
        private Vector3 _startV3;
        private Vector3 _targetV3;
        private Vector3 _bezierV3;

        #region Color
        private Graphic _graphic;
        private Color _startColor;
        private Color _targetColor;
        #endregion

        private float _time;
        private MoveType _moveType;
        private TweenType _tweenType;

        public static EffectTweenRtPosObj CreateMove(RectTransform rectTransform, Vector2 targetVal, float time)
        {
            var tweenObj = EffectTween.Instance.effectTweenRtPosPool.Create();
            tweenObj.gameObject = rectTransform.gameObject;
            tweenObj._rectTransform = rectTransform;
            tweenObj._startV3 = rectTransform.anchoredPosition;
            tweenObj._targetV3 = targetVal;
            tweenObj._dt = 0;
            tweenObj._time = time;
            tweenObj._moveType = MoveType.Anchored;
            tweenObj._tweenType = TweenType.Lerp;
            return tweenObj;
        }

        public static EffectTweenRtPosObj CreateBezierMove(RectTransform rectTransform, Vector2 targetVal, Vector2 bezierVal, float time)
        {
            var tweenObj = EffectTween.Instance.effectTweenRtPosPool.Create();
            tweenObj.gameObject = rectTransform.gameObject;
            tweenObj._rectTransform = rectTransform;
            tweenObj._startV3 = rectTransform.anchoredPosition;
            tweenObj._targetV3 = targetVal;
            tweenObj._dt = 0;
            tweenObj._bezierV3 = bezierVal;
            tweenObj._time = time;
            tweenObj._moveType = MoveType.Anchored;
            tweenObj._tweenType = TweenType.Bezier;
            return tweenObj;
        }
        
        public static EffectTweenRtPosObj CreateMove(GameObject gameObject, Vector3 targetVal, float time)
        {
            var tweenObj = EffectTween.Instance.effectTweenRtPosPool.Create();
            tweenObj.gameObject = gameObject;
            tweenObj._transform = gameObject.transform;
            tweenObj._startV3 = gameObject.transform.localPosition;
            tweenObj._targetV3 = targetVal;
            tweenObj._dt = 0;
            tweenObj._time = time;
            tweenObj._moveType = MoveType.Position;
            tweenObj._tweenType = TweenType.Lerp;
            return tweenObj;
        }

        public static EffectTweenRtPosObj CreateMoveLocal(GameObject gameObject, Vector3 targetVal, float time)
        {
            var tweenObj = EffectTween.Instance.effectTweenRtPosPool.Create();
            tweenObj.gameObject = gameObject;
            tweenObj._transform = gameObject.transform;
            tweenObj._startV3 = gameObject.transform.localPosition;
            tweenObj._targetV3 = targetVal;
            tweenObj._dt = 0;
            tweenObj._time = time;
            tweenObj._moveType = MoveType.LocalPosition;
            tweenObj._tweenType = TweenType.Lerp;
            return tweenObj;
        }

        public static EffectTweenRtPosObj CreateScale(Transform transform, Vector3 targetVal, float time)
        {
            var tweenObj = EffectTween.Instance.effectTweenRtPosPool.Create();
            tweenObj.gameObject = transform.gameObject;
            tweenObj._transform = transform;
            tweenObj._startV3 = transform.localScale;
            tweenObj._targetV3 = targetVal;
            tweenObj._dt = 0;
            tweenObj._time = time;
            tweenObj._moveType = MoveType.Scale;
            tweenObj._tweenType = TweenType.Lerp;
            return tweenObj;
        }

        public static EffectTweenRtPosObj CreateRotate(Transform transform, Vector3 targetVal, float time)
        {
            var tweenObj = EffectTween.Instance.effectTweenRtPosPool.Create();
            tweenObj.gameObject = transform.gameObject;
            tweenObj._transform = transform;
            tweenObj._startV3 = transform.localEulerAngles;
            tweenObj._targetV3 = targetVal;
            tweenObj._dt = 0;
            tweenObj._time = time;
            tweenObj._moveType = MoveType.Rotate;
            tweenObj._tweenType = TweenType.Lerp;
            return tweenObj;
        }
        
        public static EffectTweenRtPosObj CreateAutoRotate(Transform transform, Vector3 targetVal, float time)
        {
            var tweenObj = EffectTween.Instance.effectTweenRtPosPool.Create();
            tweenObj.gameObject = transform.gameObject;
            tweenObj._transform = transform;
            tweenObj._startV3 = transform.localEulerAngles;
            tweenObj._targetV3 = targetVal;
            tweenObj._dt = 0;
            tweenObj._time = time;
            tweenObj._moveType = MoveType.AutoRotate;
            tweenObj._tweenType = TweenType.Lerp;
            return tweenObj;
        }
        

        public static EffectTweenRtPosObj CreateColor(Graphic graphic, Color targetVal, float time)
        {
            var tweenObj = EffectTween.Instance.effectTweenRtPosPool.Create();
            tweenObj.gameObject = graphic.gameObject;
            tweenObj._graphic = graphic;
            tweenObj._startColor = graphic.color;
            tweenObj._targetColor = targetVal;
            tweenObj._dt = 0;
            tweenObj._time = time;
            tweenObj._moveType = MoveType.ImageColor;
            tweenObj._tweenType = TweenType.Lerp;
            return tweenObj;
        }

        public static EffectTweenRtPosObj CreateSizeDelta(RectTransform rectTransform, Vector2 targetVal, float time)
        {
            var tweenObj = EffectTween.Instance.effectTweenRtPosPool.Create();
            tweenObj.gameObject = rectTransform.gameObject;
            tweenObj._rectTransform = rectTransform;
            tweenObj._startV3 = rectTransform.sizeDelta;
            tweenObj._targetV3 = targetVal;
            tweenObj._dt = 0;
            tweenObj._time = time;
            tweenObj._moveType = MoveType.SizeDelta;
            tweenObj._tweenType = TweenType.Lerp;
            return tweenObj;
        }

        public override bool Excute(float dt)
        {
            _dt += dt;
            Vector3 val = Vector3.zero;
            if (_moveType != MoveType.Rotate && _moveType != MoveType.ImageColor)
            {
                if (_tweenType == TweenType.Lerp)
                {
                    val = NMathf.Lerp(_startV3, _targetV3, _dt, _time);
                }
                else if (_tweenType == TweenType.Bezier)
                {
                    var p1 = NMathf.Lerp(_startV3, _bezierV3, _dt, _time);
                    var p2 = NMathf.Lerp(_bezierV3, _targetV3, _dt, _time);
                    val = NMathf.Lerp(p1, p2, _dt, _time);
                }
            }

            switch (_moveType)
            {
                case MoveType.Anchored:
                    _rectTransform.anchoredPosition = val;
                    break;
                case MoveType.Position:
                    _transform.position = val;
                    break;
                case MoveType.LocalPosition:
                    _transform.localPosition = val;
                    break;
                case MoveType.Scale:
                    _transform.localScale = val;
                    break;
                case MoveType.Rotate:
                    _transform.localEulerAngles = NMathf.LerpAngle(_startV3, _targetV3, _dt, _time);
                    break;
                case MoveType.AutoRotate:
                    _transform.localEulerAngles = val;
                    break;
                case MoveType.ImageColor:
                    _graphic.color = NMathf.Lerp(_startColor, _targetColor, _dt, _time);
                    break;
                case MoveType.SizeDelta:
                    _rectTransform.sizeDelta = val;
                    break;
            }

            return _dt >= _time;
        }

        public override void Destroy()
        {
            EffectTween.Instance.effectTweenRtPosPool.Recycle(this);
        }

        public override void DoPingPong()
        {
            if (_moveType == MoveType.ImageColor)
            {
                var tempColor = _startColor;
                _startColor = _targetColor;
                _targetColor = tempColor;
            }
            else
            {
                var tempV3 = _startV3;
                _startV3 = _targetV3;
                _targetV3 = tempV3;
            }
        }
    }
}